/*
 * @Author       : wang chao
 * @Date         : 2023-10-11 15:11:20
 * @LastEditors: wangchao
 * @LastEditTime: 2024-10-04 14:48:47
 * @FilePath: \JD-RTT-Driver\dev_rtu\dev_rtu_mb_master_app.c
 * @Description  :
 * Copyright 2023 BingShan, All Rights Reserved.
 */
#include "stdio.h"
#include "string.h"
#include "board.h"
#include "dev_rtu_mb.h"
#include "dev_rtu_virtualIO.h"
//

#define DBG_TAG "SMRTU_MASTER"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>

#define RTU_ADDR_RUN_CURRENT 0x3000

#define TARGET_PARAMS RTU_ADDR_RUN_CURRENT

/* 定义互斥量控制块 */
static rt_mutex_t mb_sm_master_mux = RT_NULL;
static rt_bool_t mb_sm_master_startup = RT_FALSE;

// 收发控制引脚回调函数
static int uart_rts(int on)
{
    return 0;
}

static void rs485_pin_init(void)
{
}

/***
 * 读取从站信息定义
 */
uint8_t dev_rtu_master_print_enable = 0;
uint8_t dev_rtu_master_print_temp_enable = 0;

static dev_rtu_mb_t modbus_dev_rtu_master = {0};

rt_bool_t set_dev_rtu_master_print_enable(uint8_t val)
{
    dev_rtu_master_print_enable = val;
}

uint8_t get_dev_rtu_master_print_enable(void)
{
    return dev_rtu_master_print_enable;
}

static uint16_t recv_buff[5];
static rt_uint16_t slave_holding_register_value[5] = {0};

rt_uint16_t get_dev_rtu_holding_register_value(rt_uint16_t index)
{
    return slave_holding_register_value[index];
}

#define MB_MASTER_SCAN_RATIO 500
rt_uint16_t current_vf_run_freq[4] = {0};

static rt_uint8_t dev_rtu_comm_error_pcnt = 0;
static rt_uint8_t dev_rtu_comm_error_ncnt = 0;
static rt_bool_t dev_rtu_comm_fault = RT_FALSE;

#define SMRTU_FAULT_COUNT 45

rt_bool_t get_dev_rtu_comm_fault(void)
{
    if (dev_rtu_comm_error_pcnt >= SMRTU_FAULT_COUNT || dev_rtu_comm_error_ncnt >= SMRTU_FAULT_COUNT)
    {
        return RT_TRUE;
    }
    return RT_FALSE;
}

/**
 *  从站温度数据
 */
static rt_int16_t slave_temp_register_value[10] = {0};
static rt_int16_t slave_temp_register_cache[10] = {0};

void dev_rtu_master_poll(dev_rtu_mb_t* smb_master)
{
    int rc = 0, rc_state = 0;
    rt_uint16_t index = 0;

    while (1)
    {
        rt_thread_mdelay(MB_MASTER_SCAN_RATIO);
        // --------------- READ F03 From 1#正极泵---------------
        rt_mutex_take(mb_sm_master_mux, RT_WAITING_FOREVER);
        //
        dev_rtu_mb_error_recovery(smb_master);
        dev_rtu_mb_set_slave(smb_master, 11);
        rc = dev_rtu_mb_read_registers(smb_master, TARGET_PARAMS, 1, recv_buff);
        if (rc >= MODBUS_OK)
        {
            current_vf_run_freq[0] = recv_buff[0];
        }
        else
        {
            LOG_E("VFB: P1 rtu read x03 reg error:%d", rc);
        }
        rt_mutex_release(mb_sm_master_mux);
        rt_thread_mdelay(MB_MASTER_SCAN_RATIO);
        // --------------- READ F03 From 2#正极泵---------------
        rt_mutex_take(mb_sm_master_mux, RT_WAITING_FOREVER);
        //
        dev_rtu_mb_error_recovery(smb_master);
        dev_rtu_mb_set_slave(smb_master, 22);
        rc = dev_rtu_mb_read_registers(smb_master, TARGET_PARAMS, 1, recv_buff);
        if (rc >= MODBUS_OK)
        {
            current_vf_run_freq[1] = recv_buff[0];
        }
        else
        {
            LOG_E("VFB: P2 rtu read x03 reg error:%d", rc);
        }
        rt_mutex_release(mb_sm_master_mux);
        rt_thread_mdelay(MB_MASTER_SCAN_RATIO);
        // --------------- READ F03 From 1#负极泵---------------
        rt_mutex_take(mb_sm_master_mux, RT_WAITING_FOREVER);
        //
        dev_rtu_mb_error_recovery(smb_master);
        dev_rtu_mb_set_slave(smb_master, 33);
        rc = dev_rtu_mb_read_registers(smb_master, TARGET_PARAMS, 1, recv_buff);
        if (rc >= MODBUS_OK)
        {
            current_vf_run_freq[2] = recv_buff[0];
        }
        else
        {
            LOG_E("VFB: N1 rtu read x03 reg error:%d", rc);
        }
        rt_mutex_release(mb_sm_master_mux);
        rt_thread_mdelay(MB_MASTER_SCAN_RATIO);
        // --------------- READ F03 From 1#负极泵---------------
        rt_mutex_take(mb_sm_master_mux, RT_WAITING_FOREVER);
        //
        dev_rtu_mb_error_recovery(smb_master);
        dev_rtu_mb_set_slave(smb_master, 44);
        rc = dev_rtu_mb_read_registers(smb_master, TARGET_PARAMS, 1, recv_buff);
        if (rc >= MODBUS_OK)
        {
            current_vf_run_freq[3] = recv_buff[0];
        }
        else
        {
            LOG_E("VFB: N2 rtu read x03 reg error:%d", rc);
        }
        rt_mutex_release(mb_sm_master_mux);
    }
}

static void device_rtu_master_thread_entry(void* param)
{
    dev_rtu_mb_t* smb_master = param;

    rs485_pin_init();

    mb_sm_master_mux = rt_mutex_create("mb_master_mux", RT_IPC_FLAG_PRIO);

    dev_rtu_mb_init(smb_master, MODBUS_CORE_RTU, dev_rtu_mb_port_rtdevice_create(SMRTU_UART_DEVICE_NAME));

    struct serial_configure serial_config;
    serial_config.baud_rate = BAUD_RATE_9600;
    serial_config.data_bits = DATA_BITS_8;
    serial_config.stop_bits = STOP_BITS_1;
    serial_config.bufsz = 512;
    serial_config.parity = PARITY_NONE;
    dev_rtu_mb_dev_rtu_set_serial_config(smb_master, &serial_config);

    dev_rtu_mb_dev_rtu_set_serial_rts(smb_master, uart_rts);
    dev_rtu_mb_dev_rtu_set_oflag(smb_master, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_DMA_RX);
    dev_rtu_mb_connect(smb_master);
    //
    dev_rtu_master_poll(smb_master);
}

void dev_rtu_master_write_to_slave(int device, int reg, int val)
{
    int rc = 0, retry = 0;

    if (mb_sm_master_startup)
    {
        dev_rtu_mb_t* smb_master = &modbus_dev_rtu_master;

        dev_rtu_mb_set_slave(smb_master, device);
        rt_thread_mdelay(20);

        rt_mutex_take(mb_sm_master_mux, RT_WAITING_FOREVER);
        rc = rmb_write_register(smb_master, reg, val);
        if (rc >= MODBUS_OK)
        {
            LOG_I("Write to VFB:%d ok: addr:0x%x val:%d", device, reg, val);
        }
        else
        {
            LOG_E("Write to VFB:0x%x Error", device);
        }

        rt_mutex_release(mb_sm_master_mux);
    }
}

rt_uint16_t manual_freq_data[4] = {0};

rt_uint16_t get_manual_freq_data(rt_uint8_t idx)
{
    if (idx >= 0 && idx < 4)
    {
        return manual_freq_data[idx];
    }
    return 0;
}

void set_manual_freq_data(rt_uint8_t idx, rt_uint16_t value)
{
    if (idx >= 0 && idx < 4)
    {
        manual_freq_data[idx] = value;
    }
}

void reset_manual_freq_data(void)
{
    extern rt_int16_t get_app_params(rt_uint16_t index);
    rt_uint16_t default_freq = get_app_params(38);
    LOG_I("VF Default Freq:%d", default_freq);
    //
    manual_freq_data[0] = default_freq;
    manual_freq_data[1] = default_freq;
    manual_freq_data[2] = default_freq;
    manual_freq_data[3] = default_freq;
    //
    dev_rtu_master_write_to_slave(11, 0x2001, manual_freq_data[0]);
    dev_rtu_master_write_to_slave(22, 0x2001, manual_freq_data[1]);
    dev_rtu_master_write_to_slave(33, 0x2001, manual_freq_data[2]);
    dev_rtu_master_write_to_slave(44, 0x2001, manual_freq_data[3]);
}

void vfb_manual_ctrl(int slave_id, int frequency)
{
    int val = frequency;
    dev_rtu_master_write_to_slave(slave_id, 0x2001, val);
}

void dev_rtu_write_double_device(rt_uint16_t cha_dev, rt_uint16_t cha_reg, rt_uint16_t cha_val, rt_uint16_t chb_dev, rt_uint16_t chb_reg, rt_uint16_t chb_val)
{
    rt_mutex_take(mb_sm_master_mux, RT_WAITING_FOREVER);

    int rc = 0, retry = 0;

    if (mb_sm_master_startup)
    {
        dev_rtu_mb_t* smb_master = &modbus_dev_rtu_master;

        // write a
        dev_rtu_mb_set_slave(smb_master, cha_dev);
        rt_thread_mdelay(20);
        rc = rmb_write_register(smb_master, cha_reg, cha_val);
        if (rc >= MODBUS_OK)
        {
            ;
        }
        else
        {
            LOG_E("mb sm rtu write to slave error: %d", rc);
        }
        rt_thread_mdelay(100);

        // write b
        dev_rtu_mb_set_slave(smb_master, chb_dev);
        rt_thread_mdelay(20);
        rc = rmb_write_register(smb_master, chb_reg, chb_val);
        if (rc >= MODBUS_OK)
        {
            ;
        }
        else
        {
            LOG_E("mb sm rtu write to slave error: %d", rc);
        }
    }

    rt_mutex_release(mb_sm_master_mux);
}

int bms_device_rtu_master_thread(void)
{
    rt_thread_t thread_id;

    thread_id = rt_thread_create("dev_rtu_m", device_rtu_master_thread_entry, &modbus_dev_rtu_master, 1024, 14, 20);
    if (thread_id != RT_NULL)
    {
        rt_thread_startup(thread_id);
        mb_sm_master_startup = RT_TRUE;
    }
    else
    {
        goto __exit;
    }
    return RT_EOK;
__exit:
    if (thread_id)
        rt_thread_delete(thread_id);
    return RT_ERROR;
}
